﻿using System;
using System.Collections.Generic;
using System.Linq;
using Randomize.Core.Descriptors;
using Randomize.Core.Exceptions;
using Randomize.Core.Generators;

namespace Randomize.Core
{
    public class Randomizer
    {
        private readonly List<IGenerator> _generators;

        private readonly Random _random;

        public Randomizer()
        {
            _random = new Random();
            _generators = new List<IGenerator>
                          {
                              new StringGenerator(_random),
                              new DoubleGenerator(_random),
                              new IntGenerator(_random),
                              new DateTimeGenerator(_random)
                          };
        }

        public T Generate<T>()
        {
            var generator = this.GetGenerator<T>();
            if (generator == null)
            {
                throw new UnregisteredTypeException(typeof(T));
            }

            return generator.Generate();
        }

        public IEnumerable<T> Generate<T>(int count)
        {
            var generator = this.GetGenerator<T>();

            if (generator == null)
            {
                throw new UnregisteredTypeException(typeof(T));
            }

            for(int i = 0; i < count; i++)
            {
                yield return generator.Generate();
            }
        }

        public Randomizer Register<T>(IGenerationDescriptor<T> descriptor)
        {   
            if (descriptor == null)
            {
                throw new ArgumentNullException("descriptor");
            }

            _generators.Add(descriptor.CreateGenerator(_random));
            return this;
        }

        private IGenerator<T> GetGenerator<T>()
        {
            return _generators
                .OfType<IGenerator<T>>()
                .SingleOrDefault();
        }
    }
}
